define(function (require, exports, module) {
    var PDFPoint = WebPDF.PDFPoint;
    var CommonTools = WebPDF.Common;
    WebPDF.DrawingAnnotHandler = function (readerApp, annotHandlerManager) {
        this.readerApp = readerApp;
        this.annotHandlerManager = annotHandlerManager;
    };

    WebPDF.DrawingAnnotHandler.prototype =
    {
        getType: function () {
            return "Ink";
        },
        canAnswer: function (annot, bAllowSelectTextTool) {
            if (!this.readerApp.isEditable())
                return false;
            var type = annot.getSubType();
            var tool = this.readerApp.getCurToolHandler();
            if (tool){
                var toolName = tool.getName();
                if (toolName===WebPDF.Tools.TOOL_NAME_INKANNOT || toolName === WebPDF.Tools.TOOL_NAME_HAND ||
                    toolName === this.annotType){
                    return true;
                }
                if (bAllowSelectTextTool != undefined && bAllowSelectTextTool) {
                    if (toolName === WebPDF.TOOL_NAME_SELECTTEXT) {
                        return true;
                    }
                }
            }
            return false;
        },
        canMove: function (subType) {
            return true;
        },
        moveAnnot: function (pageView, selectedAnnot,
                             offsetX, offsetY ,newPosX, newPosY) {
            var annotUIManager = this.annotHandlerManager.getUIManager();
            selectedAnnot.offsetInkList(offsetX, offsetY);
            var annotName = selectedAnnot.getAnnotName();
            var annotDivID = annotUIManager.getAnnotDivID(pageView, annotName);
            var jqAnnotDiv = $("#" + annotDivID);
            jqAnnotDiv.css({
                left: newPosX + "px",
                top: newPosY + "px"
            });
            var annotRectDivID = annotUIManager.getTextAnnotDivID(pageView, annotName);
            var jqAnnotRect = $("#" + annotRectDivID);
            jqAnnotRect.css({
                left: newPosX + "px",
                top: newPosY + "px"
            });
            /*
            var annotDrawingDivID = annotUIManager.getAnnotCanvasDivID(pageView, annotName);
            var jqueryCanvas = $("#" + annotDrawingDivID);
            jqueryCanvas.css({
                left: newPosX + "px",
                top: newPosX + "px"
            });*/
        },
        deleteAnnot: function (pageView, annot) {
            var annotName = annot.getAnnotName();
            var annotUIManager = this.annotHandlerManager.getUIManager();
            var annotDivID = annotUIManager.getAnnotDivID(pageView, annotName);
            $("#" + annotDivID).remove();
            var annotShowDivID = annotUIManager.getInkAnnotDivID(pageView, annotName);
            $("#" + annotShowDivID).remove();
            var popup = annot.getPopup();
            if (popup == null || annot.getHeadAnnot() != null) {
                return;
            }
            var popupDivID = annotUIManager.getAnnotPopupDivID(pageView, annotName);
            $("#" + popupDivID).remove();
        },
        onDraw: function (pageView, annot, isRedraw, extraScale) {           
            extraScale = $.isNumeric(extraScale) ? extraScale : 1;
            var annotName = annot.getAnnotName();
            var annotUIManager = this.annotHandlerManager.getUIManager();
            var canvasID = annotUIManager.getAnnotCanvasDivID(pageView, annotName);
            var objCanvas = document.getElementById(canvasID);
            if (objCanvas != null && !isRedraw && !$.support.canvas) {
                uuClass.Canvas.InitCavansElement(objCanvas);
                objCanvas = document.getElementById(canvasID);
            }
            if (!objCanvas)  {
                return;
            }
            var objCanvas2DContext = objCanvas.getContext('2d');
            if (objCanvas2DContext._clear != null) {
                objCanvas2DContext._clear();
            }
            else{
                objCanvas2DContext.clearRect(0, 0, objCanvas.width, objCanvas.height);
            }
            objCanvas2DContext.lineWidth = annot.getInkBorderWidth() * pageView.getScale() * extraScale;
            objCanvas2DContext.strokeStyle = WebPDF.Common.hexColor2Rgba(annot.getInkColor(), 1.0);
            var annotPDFRect = annot.getRect();
            var annotDocRect = pageView.pdfToDoc(annotPDFRect, true);
            var inkList = annot.getInkList();
            if (inkList != null) {
                objCanvas2DContext.beginPath();
                var iInkArrayCnt = inkList.length;
                for (var i = 0; i < iInkArrayCnt; i++) {
                    var inkArray = inkList[i];
                    var ptCount = inkArray.length;
                    if (ptCount <= 1)
                        continue;
                    var docPtArray = [];
                    for (var k = 0; k < ptCount; k++) {
                        var docPt = pageView.pdfPtToDoc(inkArray[k]);
                        docPt.x = (docPt.x - annotDocRect.left) * extraScale;
                        docPt.y = (docPt.y - annotDocRect.top) * extraScale;
                        docPtArray.push(docPt);
                    }
                    var fp = docPtArray[0];
                    objCanvas2DContext.moveTo(fp.x, fp.y);
                    if (ptCount == 1) {
                        var pt = docPtArray[1];
                        objCanvas2DContext.lineTo(pt.x, pt.y);
                        objCanvas2DContext.stroke();
                    }
                    else {

                        var point0 = new PDFPoint(0.0, 0.0), point1 = new PDFPoint(0.0, 0.0),
                            point2 = new PDFPoint(0.0, 0.0), point3 = new PDFPoint(0.0, 0.0);
                        var vector1 = new PDFPoint(0.0, 0.0), vector2 = new PDFPoint(0.0, 0.0);
                        var vSlope1, vSlope2;
                        var j = 1;
                        point0 = fp;

                        do {
                            objCanvas2DContext.moveTo(point0.x, point0.y);
                            if ((ptCount - j) == 1) {
                                point3 = docPtArray[j++];
                                point1.x = (point0.x * 2.0 + point3.x) / 3.0;
                                point1.y = (point0.y * 2.0 + point3.y) / 3.0;
                                point2.x = (point0.x + point3.x * 2.0) / 3.0;
                                point2.y = (point0.y + point3.y * 2.0) / 3.0;

                                objCanvas2DContext.bezierCurveTo(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y);
                                point0 = point3;
                            }
                            else if ((ptCount - j) == 2) {
                                point1 = docPtArray[j++];
                                point2 = docPtArray[j];
                                vector1.x = point1.x - point0.x;
                                vector1.y = point1.y - point0.y;
                                vector2.x = point2.x - point1.x;
                                vector2.y = point2.y - point1.y;
                                if (CommonTools.vectorLength(vector1) < 0.001)
                                    vSlope1 = 0.0;
                                else
                                    vSlope1 = CommonTools.slopeAngle(vector1);
                                if (CommonTools.vectorLength(vector2) < 0.001)
                                    vSlope2 = 0.0;
                                else
                                    vSlope2 = CommonTools.slopeAngle(vector2);

                                if (Math.abs(vSlope1 - vSlope2) > 3.1415926535 / 3.0) {
                                    point3 = point1;
                                    point1.x = (point0.x * 2.0 + point3.x) / 3.0;
                                    point1.y = (point0.y * 2.0 + point3.y) / 3.0;
                                    point2.x = (point0.x + point3.x * 2.0) / 3.0;
                                    point2.y = (point0.y + point3.y * 2.0) / 3.0;
                                    objCanvas2DContext.moveTo(point0.x, point0.y);
                                    objCanvas2DContext.bezierCurveTo(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y);
                                    point0 = point3;
                                }
                                else {
                                    //csTemp.Format("%.3f %.3f %.3f %.3f v\n", point1.x, point1.y, point2.x, point2.y);
                                    objCanvas2DContext.moveTo(point0.x, point0.y);
                                    objCanvas2DContext.bezierCurveTo(point0.x, point0.y, point1.x, point1.y, point2.x, point2.y);
                                    j++;
                                    point0 = point2;
                                }
                            }
                            else {
                                point1 = docPtArray[j++];
                                point2 = docPtArray[j];
                                point3 = docPtArray[j + 1];
                                objCanvas2DContext.bezierCurveTo(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y);
                                j += 2;
                                point0 = point3;
                            }
                        } while (j < ptCount);
                    }
                }
                objCanvas2DContext.stroke();
            }
        },
        onSelected: function (pageView, annot) {            
            var annotName = annot.getAnnotName();
            var annotUIManager = this.annotHandlerManager.getUIManager();
            var annotDivID = annotUIManager.getAnnotDivID(pageView, annotName);
            $("#" + annotDivID).addClass("fwr-annot-selected");          
            return true;
        },
        onDeSelected: function(pageView, annot){
            var annotName = annot.getAnnotName();
            var annotUIManager = this.annotHandlerManager.getUIManager();
            var annotDivID = annotUIManager.getAnnotDivID(pageView, annotName);
            $("#" + annotDivID).removeClass("fwr-annot-selected");
        },
        onFocus: function(pageView, annot){
            this.annotHandlerManager.getMarkupAnnotHandler().onFocus(pageView, annot);
        },
        onLButtonDown: function(pageView,annot, event){
            return this.onSelected(pageView,annot);
        },
        onLButtonUp: function(pageView, annot, event){
        },
        onLButtonDblClk: function(pageView,annot, event){
            this.annotHandlerManager.getMarkupAnnotHandler().onLButtonDblClk(pageView, annot,event);
        },
        onMouseOver: function(pageView, annot, event){
            this.annotHandlerManager.getMarkupAnnotHandler().onMouseOver(pageView, annot,event);
        },
        onMouseLeave : function (pageView, annot, event) {
            this.annotHandlerManager.getMarkupAnnotHandler().onMouseLeave(pageView, annot,event);
        },
        onUpdatePosition: function(pageView, annot, visibleRect){
            var annotPDFRect = annot.getRect();
            var annotDocRect = pageView.pdfToDoc(annotPDFRect, true);           
            var annotUIManager = this.annotHandlerManager.getUIManager();
            var annotShowDivID = annotUIManager.getAnnotDivID(pageView, annot.getAnnotName());
            
          
            var canvasID = annotUIManager.getAnnotCanvasDivID(pageView, annot.getAnnotName());
            $("#" + annotShowDivID).css({
                left: annotDocRect.left,
                top: annotDocRect.top,
                width: WebPDF.RectUtils.width(annotDocRect),
                height: WebPDF.RectUtils.height(annotDocRect)
            });
            var objCanvas = document.getElementById(canvasID);
            if (objCanvas != null) {
                $(objCanvas).height(WebPDF.RectUtils.height(annotDocRect));
                $(objCanvas).width(WebPDF.RectUtils.width(annotDocRect));
                $(objCanvas).attr("width", WebPDF.RectUtils.width(annotDocRect));
                $(objCanvas).attr("height", WebPDF.RectUtils.height(annotDocRect));
            }
            this.onDraw(pageView, annot, true, 1);          
        }
    };


    return WebPDF.DrawingAnnotHandler;
});